//Ye Kaiqi and Nguyen Trung Hieu
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import com.joestelmach.natty.*;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;

import org.apache.log4j.Logger;


public class Controller {
	static Logger logger = Logger.getLogger(Controller.class.getName());
	
	//for adding a task
	private List<DateGroup> dateGroups;
	private List<Date> dates;
	
	//for deciding showing the search result or tasks in the storage
	private boolean searchTodoFlag;
	private boolean searchDoneFlag;
	private boolean searchOverdueFlag;
	private Vector<Task> searchTodoResult;
	private Vector<Task> searchDoneResult;
	private Vector<Task> searchOverdueResult;
	
	//for user to change the reminder setting
	private int reminderFrequency;
	private Long reminderBeforeTime;
	private int reminderHour;
	private int reminderMinute;
	private int reminderSecond;
	private boolean isReminderInputCorrect;
	
	public TaskHandling toDoHandling;
	public TaskHandling doneHandling;
	public TaskHandling overdueHandling;
	
	private PriSecUndoRedo undoManager;
	private SimpleUEListener simpleListener;
	public PriSecGui gui;
	private boolean editInfoCorrect;
	
	private String editDesc;
	private String editTime;
	private String editDate;

	public Controller() {
		dateGroups = null;
		dates = null;
		gui = new PriSecGui();
		searchTodoFlag = false;
		searchDoneFlag = false;
		searchOverdueFlag = false;
		searchTodoResult = new Vector<Task>();
		searchDoneResult = new Vector<Task>();
		searchOverdueResult = new Vector<Task>();
		reminderHour = 0;
		reminderMinute = 0;
		reminderSecond = 0;
		isReminderInputCorrect = true;
		toDoHandling = new TaskHandling("PriSecTasks.txt");
		doneHandling = new TaskHandling("PriSecDoneTasks.txt");
		overdueHandling = new TaskHandling("PriSecOverdueTasks.txt");
		undoManager = new PriSecUndoRedo();
		simpleListener = new SimpleUEListener(undoManager);
		toDoHandling.addUndoableEditListener(simpleListener);
		doneHandling.addUndoableEditListener(simpleListener);
		overdueHandling.addUndoableEditListener(simpleListener);
		editInfoCorrect = true;
	}
	
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		@SuppressWarnings("unused")
		boolean isOverdueTakenPlace = false;
		
		Controller control = new Controller();
		
		//get the settings for the reminder
		control.reminderFrequency = control.gui.getReminderFreq();
		control.reminderBeforeTime = control.gui.getReminderTime();
		
		//initial a Calendar at the first time the user opens the software
		Calendar initialCalendar = Calendar.getInstance();
		logger.info("Controller is ready.");
		
		while (true) {
			control.updateGUI();
			
			//for checking overdue
			Vector<Task> toDoTasks = control.toDoHandling.getData();
			Vector<Task> checkOverdue = (Vector<Task>)toDoTasks.clone();

			String userInput = null;
		
			//sort by the deadline
			if(checkOverdue.size()!=0)
				Collections.sort(checkOverdue);
			
			//if there is no user input, continue checking if there are tasks overdue or
			//about to due
			while(userInput == null){
				
				//count how many tasks are about to due
				int count = 0;
				Vector<Task> checkReminder = (Vector<Task>)toDoTasks.clone();
				
				//sort by the deadline
				if(checkReminder.size() > 1)
					Collections.sort(checkReminder);

				userInput = control.gui.getUserInput();
						
				//if there is some task which is not overdue and needs to be checked
				if(checkOverdue.size()!=0){
					Task task = checkOverdue.get(0);
					if(!(task.getDate().equals("")||task.getTime().equals(""))){
						checkOverdue = control.dealWithOverdue(task, checkOverdue);
						
					}
				}
				
				Date currentDate = new Date();
				Calendar currentCalendar = Calendar.getInstance();
				if(control.gui.isReminderEnable()&&(initialCalendar.getTimeInMillis() < currentCalendar.getTimeInMillis())){
					count = control.getNumberOfTasksAboutToDue(checkReminder,currentDate);
					initialCalendar.add(Calendar.SECOND, control.reminderFrequency);
				}
				
				if(count == 1)
					control.gui.showReminding(count + " task is about to due.");
				if(count > 1)
					control.gui.showReminding(count + " tasks are about to due.");
			}
	
			String taskID = null, searchKeyWord = null;

			Character numIndex = userInput.charAt(0);
			String input = userInput.substring(1);
			String[] words = input.split(" ");
			
			if (words[0].equals("add")) {
				//logger.info("Adding a task.");
				control.initialSearch();
				control.addTask(words, input);
			}
			
			else if(words[0].equals("mark")){
				control.initialSearch();
				control.markTask(input, numIndex, words);	
			}
			
			else if (words[0].equals("undo")) {
				control.initialSearch();
				control.undo();
			}
			
			else if (words[0].equals("redo")) {
				control.initialSearch();
				control.redo();
			}
			
			else if (words[0].equals("search")) {
				control.searchTask(words, numIndex, input, searchKeyWord);	
			}
	
			// this is a delete function
			else if (words[0].equals("delete")) {
				control.initialSearch();
				control.deleteTaskByTyping(words, input, numIndex);
			}
			
			// this is an edit function
			else if (words[0].equals("edit")) {
				control.initialSearch();
				if(numIndex == 1)
					control.gui.showResponse("Sorry, tasks in Done cannot be changed");
				else if(numIndex == 2)
					control.gui.showResponse("Sorry, tasks in Overdue cannot be changed");
				else{
					try{
						int index = Integer.parseInt(words[1]);
						taskID = control.gui.getID(index);
						if(taskID == null)
							control.gui.showResponse("Invalid task index");
						else
							control.editWithTaskID(input, taskID);
					}catch(NumberFormatException e){
						control.gui.showResponse("The index is not a number");
					}
				}
			}
			
			// change the reminder frequency
			else if(words[0].equals("freq")){
				control.initialSearch();
				control.reminderHour = 0;
				control.reminderMinute = 0;
				control.reminderSecond = 0;
				control.isReminderInputCorrect = true;
				control.getReminderFrequency(input);
			}
			
			// change how much time before deadline the task is regarded as a task
			// about to due
			else if(words[0].equals("time")){
				control.initialSearch();
				control.reminderHour = 0;
				control.reminderMinute = 0;
				control.reminderSecond = 0;
				control.isReminderInputCorrect = true;
				control.getReminderTimeBeforeDeadline(input);
			}
			
			// to exit the software
			else if(words[0].equals("exit")){
				System.exit(0);
			}
	
			// mark as done by clicking
			else if (numIndex == '2') {
				control.initialSearch();

				String[] markDoneTasks = input.substring(1).split(" ");

				if(markDoneTasks.length == 1){
					if (input.substring(1).length() == 14)
						taskID = input.substring(1);
					if (input.substring(1).length() == 13)
						taskID = "0" + input.substring(1);

					
					String taskDescription = control.toDoHandling.markAsDone(taskID, control.doneHandling, -1, false).getDescription();
					control.gui.showResponse(taskDescription + " is marked as done.");
				}
				else{
						
					for(int i = 0; i < markDoneTasks.length; i++){
						if (markDoneTasks[i].length() == 13)
							markDoneTasks[i] = "0" + markDoneTasks[i];
					}
						control.toDoHandling.multipleMarkAsDone(markDoneTasks, control.doneHandling, false);

					control.gui.showResponse("All tasks are marked as done.");
				}
				
			
			}
				
			
			// delete in the todo list by clicking
			else if (numIndex == '3') { 
				control.initialSearch();
				control.deleteTaskByClicking(input, control.toDoHandling);
			}
			
			// delete in the done list by clicking
			else if (numIndex == '4') { 
				control.initialSearch();
				control.deleteTaskByClicking(input, control.doneHandling);
			}
			
	
			// editing by double clicking the column
			else if (numIndex == '5') {
				String newTime;
				String newDate;
				boolean error = false;
				control.initialSearch();
				String[] editInput = new String[5];
				taskID = input.substring(0, 14);
				
				for(int i = 0; i < 4; i++){
					int indexOfColon = input.indexOf(";");
					if(indexOfColon == -1)
						editInput[3] = input;
					else
						editInput[i] = input.substring(0,indexOfColon);
					
					if(indexOfColon + 1 >= input.length()){
						editInput[i+1] = "";
						break;
					}
					else
						input = input.substring(indexOfColon + 1);
				}
				
				try{
					error = true;
					String[] newTimeString = control.parse(editInput[2]).get(0).toString().split(" ");
					newTime = newTimeString[3];
				} catch(NullPointerException e){
					newTime = "";
					error = true;
				}
				try{
					String[] newDateString = control.parse(editInput[3]).get(0).toString().split(" ");
					newDate = newDateString[1].concat(" ").concat(newDateString[2]).concat(" ").concat(newDateString[5]);
				}catch (NullPointerException e){
					newDate = "";
				}
				control.toDoHandling.editTask(editInput[1], newTime, newDate, taskID, false);
				if (!error)
					control.gui.showResponse("The task has been edited");
				else control.gui.showResponse("Invalid input/empty fields");
			}
	
			//delete in the overduetask by clicking
			else if(numIndex == '7'){ 
				control.initialSearch();
				control.deleteTaskByClicking(input, control.overdueHandling);
			}
			
			// show all tasks after searching
			else if (words[0].equals("all")) {
				control.initialSearch();
				control.gui.showResponse("What can I do for you?");
			}
			
			//invalid command
			else
				control.gui.showResponse("Invalid command");
		}
	}

	public void undo() {
		try {
			try{
			while (this.overdueHandling.searchByTaskID(this.undoManager.editToBeUndone().toString()) != -1){
				this.undoManager.undo();
			}
			}catch(NullPointerException nPE){
				this.gui.showResponse("Cannot undo anymore!");
			}
			String undoCommand = this.undoManager.getUndoPresentationName();
				this.undoManager.undo();
				
				this.gui.showResponse(undoCommand);
		} catch (CannotUndoException ex){
			this.gui.showResponse("Cannot undo anymore!");
		}	
	}

	public void redo() {
		try {
			try{
				while (this.overdueHandling.searchByTaskID(this.undoManager.editToBeRedone().toString()) != -1){		
					this.undoManager.redo();
				}
				
				}catch(NullPointerException nPE){
					this.gui.showResponse("Cannot redo anymore!");
				}
			String redoCommand = this.undoManager.getRedoPresentationName();
				this.undoManager.redo();
				
				this.gui.showResponse(redoCommand);
			
		} catch (CannotRedoException ex){
			this.gui.showResponse("Cannot redo anymore!");
		}
	}

	public void editWithTaskID(String input, String taskID) {
		String[] infoWords = input.split("-");
		this.editInfoCorrect = true;
		this.getEditInfo(infoWords, taskID);
		
		if(this.editInfoCorrect){
			this.toDoHandling.editTask(this.editDesc, 
					this.editTime, this.editDate, 
					taskID, false);
			if (infoWords.length > 1)
				this.gui.showResponse("The task has been edited");
			else this.gui.showResponse("No information found!");
		}
	}

	public void getEditInfo(String[] infoWords, String taskID) {
		Task taskToBeEdit = this.toDoHandling.retriveTask(taskID);
		this.editDesc = taskToBeEdit.getDescription();
		this.editDate = taskToBeEdit.getDate();
		this.editTime = taskToBeEdit.getTime();
		for(int i = 1; i < infoWords.length; i++){
			if(infoWords[i].charAt(0) == 'a'){
				this.editDesc = infoWords[i].substring(2);;
			}
			
			try{	
				if(infoWords[i].charAt(0) == 't'){
					String[] newTimeString = this.parse(infoWords[i].substring(2)).get(0).toString().split(" ");
					this.editTime = newTimeString[3];
				}
			}catch(NullPointerException e){
				this.gui.showResponse("Invalid time input");
				this.editInfoCorrect = false;
			}
	
			try{
				if(infoWords[i].charAt(0) == 'd'){
					String[] newDateString = this.parse(infoWords[i].substring(2)).get(0).toString().split(" ");
					this.editDate = newDateString[1].concat(" ").concat(newDateString[2]).concat(" ").concat(newDateString[5]);
				}
			}catch(NullPointerException e){
				this.gui.showResponse("Invalid date input");
				this.editInfoCorrect = false;
			}
		}
	}

	public void markTask(String input, Character numIndex, String[] words) {
		if(words.length == 1)
			this.gui.showResponse("No task index");
		
		else{
			String idInput = input.substring(5);
			try{
				String taskID = this.gui.getID(Integer.parseInt(idInput));
				this.markTaskWithTaskIDInput(taskID, numIndex);
			}catch(NumberFormatException e){
				this.gui.showResponse("The index is not a number");
			}
		}
	}

	public void markTaskWithTaskIDInput(String taskID, Character numIndex) {
		if(taskID == null)
			this.gui.showResponse("Invalid task index");
	
		else{
			if (numIndex == '0') {
				String taskDescription = this.toDoHandling.markAsDone(taskID, this.doneHandling, -1, false).getDescription();
				this.gui.showResponse(taskDescription + " is marked as done.");
			}
		}
	}

	public Vector<Task> dealWithOverdue(Task task, Vector<Task> checkOverdue) {
		Long deadline = task.convertDeadline(task.getDate(), task.getTime());
		if (deadline < getCurrentTime()) {
			this.toDoHandling.deleteAndReturnTask(task.getID(), true);
			this.overdueHandling.addTask(task, -1, true);
			// this.gui.showResponse(task.getDescription() + " is overdue.");
			Vector<Task> toDoTasks = this.toDoHandling.getData();
			Vector<Task> overdueTasks = this.overdueHandling.getData();
			Collections.sort(toDoTasks);
			Collections.sort(overdueTasks);
			this.gui.showTaskAtToDo(toDoTasks);
			this.gui.showTaskAtOverdue(overdueTasks);
			checkOverdue.remove(0);
		}
		return checkOverdue;
	}

	//convert the current time into an integer 
	//The sequence is: year,month,date,reminderHour,reminderMinute,reminderSecond
	public static Long getCurrentTime(){
		DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Date date = new Date();
		String currentTime = dateFormat.format(date);
		String currentTimeString = currentTime.substring(0, 4);
		currentTimeString = currentTimeString.concat(currentTime.substring(5, 7));
		currentTimeString = currentTimeString.concat(currentTime.substring(8, 10));
		currentTimeString = currentTimeString.concat(currentTime.substring(11, 13));
		currentTimeString = currentTimeString.concat(currentTime.substring(14, 16));
		currentTimeString = currentTimeString.concat(currentTime.substring(17, 19));
		Long currentTimeInt = Long.parseLong(currentTimeString);
		return currentTimeInt;		
	}

	public int getNumberOfTasksAboutToDue(Vector<Task> checkReminder, Date currentDate) {
		int count = 0;
		while(checkReminder.size()!=0){
			Task task = checkReminder.get(0);
			if(!(task.getDate().equals("")||task.getTime().equals(""))){
				Date taskDate = this.parse(task.getDate().concat(" ".concat(task.getTime()))).get(0);
				if(taskDate.getTime() - this.reminderBeforeTime * 1000 < currentDate.getTime()){
					checkReminder.remove(0);
					count ++;
				}
				else
					break;
			}
			else
				break;
		}
		return count;
	}

	public void addTask(String[] words, String input) {
		if(input.contains("/")){
			String[] twoSections = input.substring(4).split("/");
			try{
				this.addTaskWithDeadline(twoSections);
			}catch(ArrayIndexOutOfBoundsException e){
				this.gui.showResponse("No description or time");
			}
		}
		else
			this.addTaskWithoutDeadline(input, words);	
	}

	public void addTaskWithDeadline(String[] twoSections) {
		String desc = twoSections[0];
		if(desc.equals(""))
			this.gui.showResponse("No task description");
		else{
			String s = this.removePrep(twoSections[1]);
			try{
				String[] deadline = this.parse(s).get(0).toString().split(" ");
				String date = deadline[1].concat(" ").concat(deadline[2]).concat(" ")
						.concat(deadline[5]);
				String time = deadline[3];
				this.toDoHandling.add(desc, date, time, false);										
				this.gui.showResponse(desc + " is added.");
				
			}catch(NullPointerException e){
				this.gui.showResponse("Invalid deadline expression");
			}
		}
	}

	public void addTaskWithoutDeadline(String input, String[] words) {
		String date = "", time = "";
		if (words.length > 1) {
			String desc = input.substring(4);
			this.toDoHandling.add(desc, date, time, false);
			this.gui.showResponse(desc + " is added.");
		}
	
		else if(words.length == 1){
			this.gui.showResponse("No task information");
		}
	}

	//use the third party library to get the time
	public List<Date> parse(String s) {
		Parser parser = new Parser();
		dateGroups = parser.parse(s);
		if (!dateGroups.isEmpty()) {
			for (DateGroup group : dateGroups) {
				dates = group.getDates();
			}
			return dates;
		}		
		else
			return null;
	}

	//remove the preposition in the deadline expression
	public String removePrep(String input) {
		String[] word = input.split(" ");
		String output = "";
		for (int i = 0; i < word.length; i++) {
			if ((word[i].equalsIgnoreCase("at"))
					|| (word[i].equalsIgnoreCase("on"))
					|| (word[i].equalsIgnoreCase("in"))
					|| (word[i].equalsIgnoreCase("by"))
					|| (word[i].equalsIgnoreCase("before"))
					|| (word[i].equalsIgnoreCase("b4"))) {
			} 
			else
				output = output.concat(word[i]).concat(" ");
		}
		return output;
	}

	public void deleteTaskByTyping(String[] words, String input,
			Character numIndex) {
		if(words.length == 1)
			this.gui.showResponse("No task index");
		
		else
			this.deleteTaskWithTaskIDInput(input, numIndex);		
	}

	public Task deleteTaskWithValidTaskID(Character numIndex, String taskID) {
		Task deletedTask = null;
		if (numIndex == '0') {
			deletedTask = this.toDoHandling.deleteAndReturnTask(taskID, false);
			this.gui.showResponse(deletedTask.getDescription() + " is removed.");
		}
		if (numIndex == '1') {
			deletedTask = this.doneHandling.deleteAndReturnTask(taskID, false);
			this.gui.showResponse(deletedTask.getDescription() + " is removed.");
		}
		if (numIndex == '6') {
			deletedTask = this.overdueHandling.deleteAndReturnTask(taskID, false);
			this.gui.showResponse(deletedTask.getDescription() + " is removed.");
		}
		return deletedTask;
	}

	public void deleteTaskWithTaskIDInput(String input, Character numIndex) {
		String idInput = input.substring(7);
		String taskID = null;
		try{
			taskID = this.gui.getID(Integer.parseInt(idInput));
		}catch(NumberFormatException e){
			this.gui.showResponse("Invalid task index");
		}
		
		if(taskID == null)
			this.gui.showResponse("Invalid task index");
	
		else{
			this.deleteTaskWithValidTaskID(numIndex, taskID);
		}
	}

	public void deleteTaskByClicking(String input, TaskHandling handling) {
		String[] deleteTasks = input.substring(1).split(" ");
		if(deleteTasks.length == 1){
			String taskID = this.getID(input.substring(1));
			Task deletedTask = handling.deleteAndReturnTask(taskID, false);	
			this.gui.showResponse(deletedTask.getDescription() + " is deleted.");
		}
		else{	
			for(int i = 0; i < deleteTasks.length; i++){
				if (deleteTasks[i].length() == 13)
					deleteTasks[i] = "0" + deleteTasks[i];
			}
			handling.multipleDelete(deleteTasks, false);			
			this.gui.showResponse("All tasks are deleted.");
		}	
	}

	public void searchTask(String[] words, Character numIndex, String input, 
			String searchKeyWord) {
		if(words.length == 1)
			this.gui.showResponse("No keyword information");
		else
			this.searchWithKeyword(numIndex, input, searchKeyWord);
	}

	public void searchWithKeyword(Character numIndex, String input, String searchKeyWord) {
		searchKeyWord = input.substring(7);
		if (numIndex == '0') {
			this.searchTodoResult = this.toDoHandling.search(searchKeyWord);
			this.searchTodoFlag = true;
		}
		if (numIndex == '1') {
			this.searchDoneResult = this.doneHandling.search(searchKeyWord);
			this.searchDoneFlag = true;
		}
		if(numIndex == '6') {
			this.searchOverdueResult = this.overdueHandling.search(searchKeyWord);
			this.searchOverdueFlag = true;
		}
	}

	public void getReminderTimeBeforeDeadline(String input) {
		int tempTime;
		String[] infoWords = input.split("-");
		for(int i = 1; i < infoWords.length; i++){
			try{
				if(infoWords[i].charAt(0) == 'h'){
					this.reminderHour = Integer.parseInt(infoWords[i].substring(2).
							replaceAll(" ", ""));
				}
			}catch(NumberFormatException e){
				this.gui.showResponse("Hour input is not a number");
				this.isReminderInputCorrect = false;
			}
			
			try{
				if(infoWords[i].charAt(0) == 'm'){
					this.reminderMinute = Integer.parseInt(infoWords[i].substring(2).
							replaceAll(" ", ""));
				}
			}catch(NumberFormatException e){
				this.gui.showResponse("Minute input is not a number");
				this.isReminderInputCorrect = false;
			}
			
			try{
				if(infoWords[i].charAt(0) == 's'){
					this.reminderSecond = Integer.parseInt(infoWords[i].substring(2).
							replaceAll(" ", ""));
				}
			}catch(NumberFormatException e){
				this.gui.showResponse("Second input is not a number");
				this.isReminderInputCorrect = false;
			}
			tempTime = reminderHour * 3600 + reminderMinute * 60 + reminderSecond;
			if(tempTime < 0)
				this.gui.showResponse("The time cannot be set less than 0");
			else if(isReminderInputCorrect){
				this.reminderBeforeTime = new Long(tempTime);
				this.gui.storeRemindSetting(this.reminderFrequency, this.reminderBeforeTime);
				this.gui.showResponse("The time is changed to " + this.reminderHour + " Hour " + 
						this.reminderMinute + " Minute " + this.reminderSecond + " Second");
			}
		}
	}

	public void getReminderFrequency(String input) {
		String[] infoWords = input.split("-");
		int tempTime;
		for(int i = 1; i < infoWords.length; i++){
			try{
				if(infoWords[i].charAt(0) == 'h'){
					this.reminderHour = Integer.parseInt(infoWords[i].substring(2).
							replaceAll(" ", ""));
				}
			}catch(NumberFormatException e){
				this.gui.showResponse("reminderHour input is not a number");
				this.isReminderInputCorrect = false;
			}
			
			try{
				if(infoWords[i].charAt(0) == 'm'){
					this.reminderMinute = Integer.parseInt(infoWords[i].substring(2).
							replaceAll(" ", ""));
				}
			}catch(NumberFormatException e){
				this.gui.showResponse("reminderMinute input is not a number");
				this.isReminderInputCorrect = false;
			}
			
			try{
				if(infoWords[i].charAt(0) == 's'){
					this.reminderSecond = Integer.parseInt(infoWords[i].substring(2).
							replaceAll(" ", ""));
				}
			}catch(NumberFormatException e){
				this.gui.showResponse("reminderSecond input is not a number");
				this.isReminderInputCorrect = false;
			}
			tempTime = this.reminderHour * 3600 + this.reminderMinute * 60 + this.reminderSecond;
			if(tempTime == 0)
				this.gui.showResponse("The time cannot be set to 0");
			else if(this.isReminderInputCorrect){
				this.reminderFrequency = tempTime;
				this.gui.storeRemindSetting(this.reminderFrequency, this.reminderBeforeTime);
				this.gui.showResponse("The time interval is changed to " + this.reminderHour + " Hour " 
						+ this.reminderMinute + " Minute " + this.reminderSecond + " Second");
			}
		}
	}

	public void markTaskWithTaskIDInput(Character numIndex, String taskID) {
		if(taskID == null)
			this.gui.showResponse("Invalid task index");
		
		else
			this.markTaskWithTaskID(numIndex, taskID);
	}

	public void markTaskWithTaskID(Character numIndex, String taskID) {
		if (numIndex == '0') {
			if(taskID == null)
				this.gui.showResponse("Invalid task index");
			else{
				Task deletedTask = this.toDoHandling.deleteAndReturnTask(taskID, false);
				Task tempTask = new Task(deletedTask.getDescription(),deletedTask.getDate(),deletedTask.getTime(),taskID);
				this.doneHandling.addTask(tempTask, -1, false);
				this.gui.showResponse(deletedTask.getDescription() + " is marked as done.");
			}
		}
	}

	public void updateGUI() {
		//search in the todo table or not
		if (this.searchTodoFlag){
			Collections.sort(this.searchTodoResult);
			this.gui.showTaskAtToDo(this.searchTodoResult);
		}
		else{
			Vector<Task> sortTasks = this.toDoHandling.getData();
			Collections.sort(sortTasks);
			this.gui.showTaskAtToDo(sortTasks);
		}
		
		//search in the done table or not 
		if (this.searchDoneFlag){
			Collections.sort(this.searchDoneResult);
			this.gui.showTaskAtDone(this.searchDoneResult);
		}
		else{
			Vector<Task> sortTasks = this.doneHandling.getData();
			Collections.sort(sortTasks);
			this.gui.showTaskAtDone(sortTasks);
		}
		
		//search in the overdue table or not
		if (this.searchOverdueFlag){
			Collections.sort(this.searchOverdueResult);
			this.gui.showTaskAtOverdue(this.searchOverdueResult);
		}
		else{
			Vector<Task> sortTasks = this.overdueHandling.getData();
			Collections.sort(sortTasks);
			this.gui.showTaskAtOverdue(sortTasks);
		}
		
	}

	//get the taskID (since the input is combination of time and date, and it starts with date
	//, so if the date has only one digit, add a 0 in the front)
	public String getID(String input) {
		if(input.length() == 14)
			return input;
		else
			return "0" + input;
	}

	//tell the system to change from showing the search result to showing the tasks' information
	public void initialSearch(){
		this.searchTodoFlag = false;
		this.searchDoneFlag = false;
		this.searchOverdueFlag = false;
	}
}
